package user

import (
	"context"
	"database/sql"
	"fmt"
	"time"

	"github.com/jmoiron/sqlx"
	"github.com/star-find-cloud/star-safe/pkg/database"
	"github.com/star-find-cloud/star-safe/pkg/logger"
)

// Repository 用户数据访问接口
type Repository interface {
	Create(ctx context.Context, user *User) error
	GetByID(ctx context.Context, id int64) (*User, error)
	GetByUsername(ctx context.Context, username string) (*User, error)
	GetByEmail(ctx context.Context, email string) (*User, error)
	Update(ctx context.Context, id int64, updateData *UpdateUserRequest) error
	Delete(ctx context.Context, id int64) error
	List(ctx context.Context, page, pageSize int) ([]*User, int64, error)
}

type userRepository struct {
	db *sqlx.DB
}

// NewRepository 创建用户数据访问实例
func NewRepository() Repository {
	return &userRepository{
		db: database.GetDB(),
	}
}

// Create 创建用户
func (r *userRepository) Create(ctx context.Context, user *User) error {
	query := `INSERT INTO users (username, email, password, phone, status, created_at, updated_at) 
		VALUES (?, ?, ?, ?, ?, ?, ?)`

	user.CreatedAt = time.Now()
	user.UpdatedAt = time.Now()

	result, err := r.db.ExecContext(ctx, query, 
		user.Username, 
		user.Email, 
		user.Password, 
		user.Phone, 
		user.Status, 
		user.CreatedAt, 
		user.UpdatedAt)
	if err != nil {
		logger.MySQLLogger.Errorf("创建用户失败: %v", err)
		return fmt.Errorf("创建用户失败: %w", err)
	}

	id, err := result.LastInsertId()
	if err != nil {
		logger.MySQLLogger.Errorf("获取插入ID失败: %v", err)
		return fmt.Errorf("获取插入ID失败: %w", err)
	}

	user.ID = id
	return nil
}

// GetByID 根据ID获取用户
func (r *userRepository) GetByID(ctx context.Context, id int64) (*User, error) {
	var user User
	query := `SELECT id, username, email, password, phone, status, created_at, updated_at, deleted_at 
		FROM users WHERE id = ? AND deleted_at IS NULL`

	err := r.db.GetContext(ctx, &user, query, id)
	if err != nil {
		if err == sql.ErrNoRows {
			return nil, fmt.Errorf("用户不存在")
		}
		logger.MySQLLogger.Errorf("查询用户失败: %v", err)
		return nil, fmt.Errorf("查询用户失败: %w", err)
	}

	return &user, nil
}

// GetByUsername 根据用户名获取用户
func (r *userRepository) GetByUsername(ctx context.Context, username string) (*User, error) {
	var user User
	query := `SELECT id, username, email, password, phone, status, created_at, updated_at, deleted_at 
		FROM users WHERE username = ? AND deleted_at IS NULL`

	err := r.db.GetContext(ctx, &user, query, username)
	if err != nil {
		if err == sql.ErrNoRows {
			return nil, fmt.Errorf("用户不存在")
		}
		logger.MySQLLogger.Errorf("查询用户失败: %v", err)
		return nil, fmt.Errorf("查询用户失败: %w", err)
	}

	return &user, nil
}

// GetByEmail 根据邮箱获取用户
func (r *userRepository) GetByEmail(ctx context.Context, email string) (*User, error) {
	var user User
	query := `SELECT id, username, email, password, phone, status, created_at, updated_at, deleted_at 
		FROM users WHERE email = ? AND deleted_at IS NULL`

	err := r.db.GetContext(ctx, &user, query, email)
	if err != nil {
		if err == sql.ErrNoRows {
			return nil, fmt.Errorf("用户不存在")
		}
		logger.MySQLLogger.Errorf("查询用户失败: %v", err)
		return nil, fmt.Errorf("查询用户失败: %w", err)
	}

	return &user, nil
}

// Update 更新用户信息
func (r *userRepository) Update(ctx context.Context, id int64, updateData *UpdateUserRequest) error {
	query := `UPDATE users SET updated_at = ?`
	params := []interface{}{time.Now()}

	if updateData.Username != "" {
		query += ", username = ?"
		params = append(params, updateData.Username)
	}
	if updateData.Email != "" {
		query += ", email = ?"
		params = append(params, updateData.Email)
	}
	if updateData.Phone != "" {
		query += ", phone = ?"
		params = append(params, updateData.Phone)
	}
	if updateData.Status != 0 {
		query += ", status = ?"
		params = append(params, updateData.Status)
	}

	query += " WHERE id = ? AND deleted_at IS NULL"
	params = append(params, id)

	result, err := r.db.ExecContext(ctx, query, params...)
	if err != nil {
		logger.MySQLLogger.Errorf("更新用户失败: %v", err)
		return fmt.Errorf("更新用户失败: %w", err)
	}

	rowsAffected, err := result.RowsAffected()
	if err != nil {
		logger.MySQLLogger.Errorf("获取影响行数失败: %v", err)
		return fmt.Errorf("获取影响行数失败: %w", err)
	}

	if rowsAffected == 0 {
		return fmt.Errorf("用户不存在或已被删除")
	}

	return nil
}

// Delete 软删除用户
func (r *userRepository) Delete(ctx context.Context, id int64) error {
	query := `UPDATE users SET deleted_at = ? WHERE id = ? AND deleted_at IS NULL`

	result, err := r.db.ExecContext(ctx, query, time.Now(), id)
	if err != nil {
		logger.MySQLLogger.Errorf("删除用户失败: %v", err)
		return fmt.Errorf("删除用户失败: %w", err)
	}

	rowsAffected, err := result.RowsAffected()
	if err != nil {
		logger.MySQLLogger.Errorf("获取影响行数失败: %v", err)
		return fmt.Errorf("获取影响行数失败: %w", err)
	}

	if rowsAffected == 0 {
		return fmt.Errorf("用户不存在或已被删除")
	}

	return nil
}

// List 分页获取用户列表
func (r *userRepository) List(ctx context.Context, page, pageSize int) ([]*User, int64, error) {
	var users []*User
	var total int64

	// 获取总数
	countQuery := `SELECT COUNT(*) FROM users WHERE deleted_at IS NULL`
	err := r.db.GetContext(ctx, &total, countQuery)
	if err != nil {
		logger.MySQLLogger.Errorf("查询用户总数失败: %v", err)
		return nil, 0, fmt.Errorf("查询用户总数失败: %w", err)
	}

	// 获取分页数据
	offset := (page - 1) * pageSize
	query := `SELECT id, username, email, phone, status, created_at, updated_at 
		FROM users WHERE deleted_at IS NULL ORDER BY id DESC LIMIT ? OFFSET ?`

	err = r.db.SelectContext(ctx, &users, query, pageSize, offset)
	if err != nil {
		logger.MySQLLogger.Errorf("查询用户列表失败: %v", err)
		return nil, 0, fmt.Errorf("查询用户列表失败: %w", err)
	}

	return users, total, nil
}
